import _Promise from 'babel-runtime/core-js/promise';
import _extends from 'babel-runtime/helpers/extends';
import _JSON$stringify from 'babel-runtime/core-js/json/stringify';
import fetch from 'isomorphic-fetch';

import appendQuery from 'append-query';
import queryString from 'query-string';
import RequestError from './RequestError';

var defaultHTTPHeaders = {
  Accept: 'application/json',
  'Content-Type': 'application/json'
};
var ajax = function ajax(method, path, body) {
  var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
      _ref$headers = _ref.headers,
      headers = _ref$headers === undefined ? defaultHTTPHeaders : _ref$headers,
      _ref$form = _ref.form,
      form = _ref$form === undefined ? false : _ref$form;

  var url = path;
  var fetchConfig = {
    method: method,
    headers: headers,
    body: body,
    credentials: 'include'
  };

  if (method !== 'get' && method !== 'delete') {
    if (!form) {
      fetchConfig.body = _JSON$stringify(body);
    } else {
      fetchConfig.body = queryString.stringify(body);

      fetchConfig.headers = _extends({}, headers, {
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
      });
    }
  }

  if (method === 'get') {
    /** FireFox ajax get request can not have a body, so let it be `null`  */
    fetchConfig.body = null;
    url = appendQuery(path, _extends({}, body, { _: new Date().getTime() }));
  }

  function handleFullfil(resolve, reject, response) {
    var status = response.status,
        statusText = response.statusText,
        ok = response.ok;


    response.json().then(function (payload) {
      // The `ok` read-only property of the Response interface contains a boolean stating
      // whether the response was successful (status in the range **200-299**) or not.
      if (ok) {
        resolve({ payload: payload });
      } else {
        // If it's not `ok` then read the `errors` from the response
        var errors = payload.errors,
            error = payload.error;


        reject(new RequestError(status, statusText, errors || error));
      }
    });
  }

  function handleReject(reject, error) {
    reject(error);
  }

  return new _Promise(function (resolve, reject) {
    return fetch(url, fetchConfig).then(handleFullfil.bind(null, resolve, reject), handleReject.bind(null, reject));
  });
};

export default ['get', 'post', 'put', 'patch', 'delete', 'head'].reduce(function (api, method) {
  var _extends2;

  return _extends({}, api, (_extends2 = {}, _extends2[method] = ajax.bind(null, method), _extends2));
}, {});